package com.danbay.cloud.account.service;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.danbay.cloud.account.dto.*;
import com.danbay.cloud.account.entity.Account;
import com.danbay.cloud.account.entity.AccountPermission;
import com.danbay.cloud.account.entity.Permission;
import com.danbay.cloud.account.entity.PermissionGroup;
import com.danbay.cloud.account.mapper.*;
import com.danbay.cloud.account.service.api.IPermissionService;
import com.danbay.framework.exception.BusinessException;
import com.danbay.framework.utils.BeanUtils;
import com.danbay.framework.utils.BeanValidator;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * @author SJG
 *         2018/1/9.
 */
@Service
public class PermissionService implements IPermissionService {

    @Autowired
    private PermissionGroupMapper permissionGroupMapper;
    @Autowired
    private AccountPermissionMapper accountPermissionMapper;
    @Autowired
    private PermissionMapper permissionMapper;
    @Autowired
    private MyPermissionMapper myPermissionMapper;
    @Autowired
    private AccountMapper accountMapper;
    @Autowired
    private LoginUserService loginUserService;


    /**
     * 添加权限定义
     *
     * @param permission 权限定义
     * @throws BusinessException 业务异常
     */
    @Override
    public void add(PermissionDto permission) throws BusinessException {
        BeanValidator.valid(permission);
        permissionMapper.insert(BeanUtils.convert(permission, Permission.class));
    }

    /**
     * 取所有权限
     *
     * @return 权限列表
     */
    @Override
    public List<PermissionInfoDto> allPermissions() {
        return BeanUtils.convert(permissionMapper.selectList(new EntityWrapper<>(new Permission())), PermissionInfoDto.class);
    }

    /**
     * 添加权限组
     *
     * @param groupDto 组信息
     * @throws BusinessException 业务异常
     */
    @Override
    public void addGroup(PermissionGroupDto groupDto) throws BusinessException {
        BeanValidator.valid(groupDto);
        checkGroupNotExist(groupDto.getParentId());
        permissionGroupMapper.insert(PermissionGroup.builder()
                .name(groupDto.getName())
                .description(groupDto.getDescription())
                .permissionIds(groupDto.getPermissionIds())
                .parentId(groupDto.getParentId())
                .addTime(DateTime.now().toDate())
                .del(false)
                .build());
    }

    /**
     * 修改权限组
     *
     * @param gid      权限组id
     * @param groupDto 权限组信息
     * @throws BusinessException 业务异常
     */
    @Override
    public void editGroup(Integer gid, PermissionGroupDto groupDto) throws BusinessException {
        BeanValidator.valid(groupDto);

        checkGroupNotExist(gid);
        PermissionGroup permissionGroup = BeanUtils.convert(groupDto, PermissionGroup.class);
        permissionGroup.setId(gid);
        permissionGroupMapper.updateById(permissionGroup);
    }

    /**
     * 取指定parentId下的权限组列表
     *
     * @param parentId 父级组Id
     * @return 权限组列表
     */
    @Override
    public List<PermissionGroupInfoDto> getGroups(Integer parentId) {
        return BeanUtils.convert(permissionGroupMapper.selectList(
                new EntityWrapper<>(PermissionGroup.builder().parentId(parentId).build())
        ), PermissionGroupInfoDto.class);
    }

    /**
     * 取所有权限组列表(不包括权限组分组)
     *
     * @return 权限组列表
     */
    @Override
    public List<PermissionGroupInfoDto> allPermissionGroups() {
        return BeanUtils.convert(permissionGroupMapper.selectList(new EntityWrapper<>(PermissionGroup.builder().type(0).build())), PermissionGroupInfoDto.class);
    }

    /**
     * 为账户分配权限
     * 指定该账户有哪些权限组，需要排除权限组中哪些权限
     *
     * @param permission 账户权限
     * @throws BusinessException 业务异常
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void assignAccountPermission(AccountPermissionDto permission) throws BusinessException {
        BeanValidator.valid(permission);

        //先删除原有的权限配置
        accountPermissionMapper.delete(new EntityWrapper<>(AccountPermission.builder()
                .userName(permission.getUserName())
                .accountGroupId(permission.getAccountGroupId())
                .build()));

        //添加新的的权限配置
        List<AccountPermissionDto.Permission> permissions = permission.getPermissions();
        if (permissions == null || permissions.size() == 0) {
            throw new BusinessException("权限组列表不能为空");
        }
        for (AccountPermissionDto.Permission p : permissions) {
            accountPermissionMapper.insert(AccountPermission.builder()
                    .userName(permission.getUserName())
                    .accountGroupId(permission.getAccountGroupId())
                    .permissionGroupId(p.getGroupId())
                    .excludePermissions(p.getExcludePermissions())
                    .build());
        }
        Account account=accountMapper.selectById(permission.getUserName());
        //缓存登录用户信息
        loginUserService.cacheLoginUserInfo(account, permission.getAccountGroupId());
    }

    /**
     * 取账户和账户组拥有的权限组列表
     *
     * @param userName 账号
     * @param groupId  账户组
     * @return 权限组列表
     * @throws BusinessException 业务异常
     */
    @Override
    public List<PermissionGroupInfoDto> getAccountPermissions(String userName, Integer groupId) throws BusinessException {
        if (userName == null || groupId == null) {
            throw new BusinessException("账号或账户组参数不能为空");
        }
        List<PermissionGroup> permissionGroups = permissionGroupMapper.getAccountPermissionGroups(AccountPermission.builder()
                .userName(userName)
                .accountGroupId(groupId)
                .build());
        return BeanUtils.convert(permissionGroups, PermissionGroupInfoDto.class);
    }

    /**
     * 检查权限分组是否存在
     *
     * @param gid 分组id
     * @return 权限分组
     * @throws BusinessException 业务异常
     */
    public PermissionGroup checkGroupNotExist(Integer gid) throws BusinessException {
        if (gid == 0) {
            return null;
        }
        assert gid != null : "gid不能为空";
        PermissionGroup group = permissionGroupMapper.selectById(gid);
        if (group == null) {
            throw new BusinessException("该权限分组不存在");
        }
        return group;
    }
}
